home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / tclX6.4c / dist / experimental / getkey.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-12  |  2.5 KB  |  95 lines

  1. /*
  2.  * getkey.c --
  3.  *
  4.  * C code for Unix System V to read single keys from the keyboard
  5.  *
  6.  *---------------------------------------------------------------------------
  7.  * 
  8.  *
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <sys/types.h>
  13. #include <termio.h>
  14.  
  15. #include <tcl.h>
  16.  
  17.  
  18. /*
  19.  *----------------------------------------------------------------------
  20.  *
  21.  * Tcl_GetKeyCmd --
  22.  *      Implements the TCL getkey command:
  23.  *        getkey [timeout]
  24.  *
  25.  * If no timeout value is specified, waits indefinitely.
  26.  *
  27.  * Results:
  28.  *      Standard TCL results.
  29.  *
  30.  *----------------------------------------------------------------------
  31.  */
  32. int
  33. Tcl_GetKeyCmd (clientData, interp, argc, argv)
  34.     ClientData  clientData;
  35.     Tcl_Interp *interp;
  36.     int         argc;
  37.     char      **argv;
  38. {
  39.     double ftimeout;
  40.     struct termio orig_term_settings;
  41.     struct termio single_char_term_settings;
  42.     unsigned char timeout;
  43.     unsigned char vmin = 0;
  44.     char c;
  45.     int returnval;
  46.  
  47.     if (argc > 2) {
  48.         Tcl_AppendResult (interp, "wrong # args: ", argv [0], 
  49.                           " [timeout]", (char *) NULL);
  50.         return TCL_ERROR;
  51.     }
  52.  
  53.     if (argc == 1) {
  54.     timeout = 0;
  55.     vmin = 1;
  56.     } else {    
  57.         if (Tcl_GetDouble (interp, argv[1], &ftimeout) != TCL_OK)
  58.             return TCL_ERROR;
  59.  
  60.     if ((ftimeout < 0.0) || (ftimeout > 25.5)) {
  61.             Tcl_AppendResult (interp, "bad timeout value: ", argv [0], 
  62.                               " timeout must be between 0.0 and 25.5",
  63.                   (char *) NULL);
  64.         return TCL_ERROR;
  65.     }
  66.     timeout = 10.0 * ftimeout;
  67.     }
  68.  
  69.     /* get their terminal settings, copy them and do a version for input
  70.      * without canonical input processing, so we can timeout input, get
  71.      * stuff without a newline, etc, etc. */
  72.     if (ioctl(0,TCGETA,&orig_term_settings) < 0) goto unixError;
  73.  
  74.     single_char_term_settings = orig_term_settings; /* structure copy */
  75.     single_char_term_settings.c_iflag &= ~(INLCR|IGNCR|ICRNL|IUCLC);
  76.     single_char_term_settings.c_lflag &= ~(ICANON|ECHO|ISIG);
  77.     single_char_term_settings.c_cc[VMIN] = vmin;
  78.     single_char_term_settings.c_cc[VTIME] = timeout;
  79.     single_char_term_settings.c_cc[VINTR] = 0377;
  80.  
  81.     if (ioctl(0,TCSETA,&single_char_term_settings) < 0) goto unixError;
  82.  
  83.     returnval = read(0,&c,1);
  84.     if (returnval > 0) sprintf(interp->result, "%c", c);
  85.  
  86.     if (ioctl(0,TCSETA,&orig_term_settings)) goto unixError;
  87.     return TCL_OK;
  88.  
  89. unixError:
  90.     Tcl_AppendResult (interp, argv[0], ": ", 
  91.                       Tcl_UnixError (interp), (char *) NULL);
  92.     return TCL_ERROR;
  93. }
  94.  
  95.